package com.ruoyi.web.controller.byw;

import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.*;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotNull;

import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.FileUtil;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.vo.*;
import com.ruoyi.common.utils.uuid.UUID;
import com.ruoyi.system.domain.*;
import com.ruoyi.system.service.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.core.io.ClassPathResource;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;
import org.springframework.web.multipart.MultipartFile;

/**
 * 用户简历库Controller
 *
 * @author ruoyi
 * @date 2024-05-25
 */
@Api("简历管理")
@RestController
@RequestMapping("/byw/tiktok-user")
public class BywTiktokUserController extends BaseController {
    @Autowired
    private IBywViteaService viteaService;

    @Autowired
    private IBywUserVitaeInfoService userVitaeInfoService;

    @Autowired
    private IBywUserBatchUnlockInfoService userBatchUnlockInfoService;

    @Autowired
    private IBywEmployeeService employeeService;

    @Autowired
    private IBywViteaOwnershipRelationService viteaOwnershipRelationService;

    @Autowired
    private IBywEmployeeImportInfoService employeeImportInfoService;

    @Autowired
    private IBywEmployeeImportViteaService employeeImportViteaService;

    @Autowired
    private IBywPositionTypeService positionTypeService;

    @Autowired
    private IBywPlacesService placesService;

    @ApiOperation("找人页面-查询")
    @PreAuthorize("@ss.hasPermi('byw:tiktok-user:list')")
    @PostMapping("/list")
    public TableDataInfo postList(@RequestBody ViteaQuery viteaQuery) {
        if (viteaQuery.getSex() != null && viteaQuery.getSex().equals(2)){
            viteaQuery.setSex(null);
        }

        Long userId = getUserId();
        viteaQuery.setUnlockedUserId(","+userId+",");
        if (viteaQuery.getDeliverHour() != null){
            viteaQuery.setDeliveryTime(new Date(DateUtils.getHourAfterEndTime(System.currentTimeMillis(), viteaQuery.getDeliverHour())));
        }
        if (CollectionUtils.isNotEmpty(viteaQuery.getCityExpect())){
            viteaQuery.setCityExpect(city(viteaQuery.getCityExpect()));
        }

        if (CollectionUtils.isNotEmpty(viteaQuery.getIntendedCity())){
            viteaQuery.setIntendedCity(city(viteaQuery.getIntendedCity()));
        }

        viteaQuery.setUnlockedNum(3);

        List<BywVitea> list = new ArrayList<>();
        List<String> userPhoneList = viteaService.selecUserPhoneList(viteaQuery);
        if (CollectionUtils.isNotEmpty(userPhoneList)){
            List<String> randomUserPhoneList = randomUserPhone(userPhoneList);
            List<BywVitea> bywViteas = viteaService.selecTiktokUserListByPhone(randomUserPhoneList.toArray(new String[0]));
            for (BywVitea bywVitea : bywViteas){
                if (StringUtils.isBlank(bywVitea.getUnlockedUserId())){
                    bywVitea.setUnlockedStatus(0);
                } else {
                    if (bywVitea.getUnlockedUserId().contains(","+userId+",")){
                        bywVitea.setUnlockedStatus(1);
                    } else {
                        bywVitea.setUnlockedStatus(0);
                    }
                }
            }

            for (String userPhone : randomUserPhoneList){
                for (BywVitea bywVitea : bywViteas){
                    if (userPhone.equals(bywVitea.getUserPhone())){
                        list.add(bywVitea);
                    }
                }
            }
        }

        TableDataInfo dataTable = getDataTable(list);

        ViteaNum vataeNum = userVitaeInfoService.vitaeNum(userId);
        Map<String, Integer> viteaNum = new HashMap<>();
        viteaNum.put("residueNum", vataeNum.getResidueNum());
        dataTable.setData(viteaNum);
        return dataTable;
    }

    private List<String> randomUserPhone(List<String> userPhoneList){
        if (userPhoneList.size() < 50){
            return userPhoneList;
        }
        Random random = new Random();
        // 使用Collections.shuffle进行原地随机排序
        Collections.shuffle(userPhoneList, random);

        // 从随机排序后的List中取前50个元素
        return userPhoneList.subList(0, 50);
    }

    private List<String> city(List<String> cityList){
        List<String> resultList = new ArrayList<>();
        for (String city :cityList){
            if(city.endsWith("市")){
                resultList.add(city.replace("市",""));
            }
            if(city.endsWith("特别行政区")){
                resultList.add(city.replace("特别行政区",""));
            }
            if(city.endsWith("自治州")){
                resultList.add(city.replace("自治州",""));
            }
        }
        return resultList;
    }

    /**
     * 解锁一个简历
     */
    @PreAuthorize("@ss.hasPermi('byw:tiktok-user:unlock')")
    @Log(title = "解锁", businessType = BusinessType.OTHER)
    @PutMapping("/unlock/{vitaePhone}")
    public AjaxResult unlock(@PathVariable("vitaePhone") @NotNull String vitaePhone) {
        ViteaNum vataeNum = userVitaeInfoService.vitaeNum(getUserId());
        // 1. 判断简历是否存在
        BywVitea bywVitea = viteaService.selectBywViteaByUserPhone(vitaePhone);
        if (bywVitea == null){
            AjaxResult error = error("简历不存在，请刷新重试");
            error.put("residueNum", vataeNum.getResidueNum());
            return error;
        }
        // 2.判断简历次数是否可解锁
        if (bywVitea.getUnlockedNum() != null && bywVitea.getUnlockedNum() > 3){
            AjaxResult error = error("不可被解锁");
            error.put("residueNum", vataeNum.getResidueNum());
            return error;
        }
        // 3.资源包用完的直接失败
        if (vataeNum.getResidueNum() <= 0){
            AjaxResult error = error("道具包不足");
            error.put("residueNum", vataeNum.getResidueNum());
            return error;
        }
        try {
            viteaService.unlock(getLoginUser().getUserId(), vitaePhone, bywVitea);
        } catch (Exception e){
            logger.error("unlock {} ,error:{}", vitaePhone, ExceptionUtils.getStackTrace(e));
            AjaxResult error = error("简历解锁失败");
            error.put("residueNum", vataeNum.getResidueNum());
            return error;
        }
        AjaxResult success = success();
        ViteaNum vataeNum2 = userVitaeInfoService.vitaeNum(getUserId());
        success.put("residueNum", vataeNum2.getResidueNum());
        return success;
    }

    /**
     * 批量解锁简历
     */
    @PreAuthorize("@ss.hasPermi('byw:tiktok-user:batch-unlock')")
    @Log(title = "批量解锁简历", businessType = BusinessType.OTHER)
    @PostMapping("/batch-unlock")
    public AjaxResult batchUnlock(@RequestBody List<String> vitaePhones) {
        Long sysUserId = getUserId();
        List<BatchUnlockVo> batchUnlockList = new ArrayList<>();

        int successNum = 0;
        for (String vitaePhone : vitaePhones){
            // 3.资源包用完的直接失败
            ViteaNum vataeNum = userVitaeInfoService.vitaeNum(sysUserId);
            if (vataeNum.getResidueNum() <= 0){
                batchUnlockList.add(BatchUnlockVo.error(vitaePhone, "道具包不足"));
                continue;
            }

            // 1. 判断简历是否存在
            BywVitea bywVitea = viteaService.selectBywViteaByUserPhone(vitaePhone);
            if (bywVitea == null){
                batchUnlockList.add(BatchUnlockVo.error(vitaePhone, "简历不存在"));
                continue;
            }
            // 2.判断简历次数是否可解锁
            if (bywVitea.getUnlockedNum() != null && bywVitea.getUnlockedNum() >= 3){
                batchUnlockList.add(BatchUnlockVo.error(vitaePhone, "不可被解锁"));
                continue;
            }

            try {
                viteaService.unlock(sysUserId, vitaePhone, bywVitea);
            } catch (Exception e){
                logger.error("unlock {} ,error:{}", vitaePhone, ExceptionUtils.getStackTrace(e));
                batchUnlockList.add(BatchUnlockVo.error(vitaePhone, "简历解锁失败"));
                continue;
            }
            batchUnlockList.add(BatchUnlockVo.succes(vitaePhone));
            successNum ++;
        }

        BywUserBatchUnlockInfo bywUserBatchUnlockInfo = new BywUserBatchUnlockInfo();
        bywUserBatchUnlockInfo.setBatchUuid(UUID.fastUUID().toString().replaceAll("-", ""));
        bywUserBatchUnlockInfo.setUnlockNum(vitaePhones.size());
        bywUserBatchUnlockInfo.setSuccessNum(successNum);
        bywUserBatchUnlockInfo.setFailureNum(vitaePhones.size() - successNum);
        bywUserBatchUnlockInfo.setCreateBy(getUserId().toString());
        userBatchUnlockInfoService.insertBywUserBatchUnlockInfo(bywUserBatchUnlockInfo);

        AjaxResult success = success(batchUnlockList);
        ViteaNum vataeNum = userVitaeInfoService.vitaeNum(getUserId());
        success.put("residueNum", vataeNum.getResidueNum());

        return success;
    }


    @ApiOperation("员工-导入模版")
    @Log(title = "用户简历库", businessType = BusinessType.IMPORT)
    @PreAuthorize("@ss.hasPermi('byw:tiktok-user:import')")
    @PostMapping("/importData")
    @Transactional(rollbackFor = Exception.class)
    public void importData(HttpServletResponse response, MultipartFile file) throws Exception
    {
        ExcelUtil<ViteaImport> util = new ExcelUtil<ViteaImport>(ViteaImport.class);
        List<ViteaImport> viteaImports = util.importExcel(file.getInputStream());
        if (CollectionUtils.isEmpty(viteaImports) || viteaImports.size()<=1){
            throw new RuntimeException("请使用标准模版，数据不能为空");
        }
        List<String> positionList = positionList();
        List<String> cityList = placesService.selectCityNameList();
        Map<String, BywEmployee> bywEmployeeMap = new HashMap<>();

        int successNum = 0;
        int index = 0;
        for (ViteaImport viteaImport : viteaImports){
            if (index == 0){
                index ++;
                continue;
            }
            String resultMsg = "";
            if(StringUtils.isBlank(viteaImport.getEmployeePhone())){
                resultMsg = resultMsg + "," + "【*手机号】不能为空";
            } else {
                if(!isPhoneNumberValid(viteaImport.getEmployeePhone())){
                    resultMsg = resultMsg + "," + "【*手机号】不符合手机号规范";
                }
            }

            if(StringUtils.isBlank(viteaImport.getUserName())){
                resultMsg = resultMsg + "," + "【*简历昵称】不能为空";
            }

            if(StringUtils.isBlank(viteaImport.getUserPhone())){
                resultMsg = resultMsg + "," + "【*简历手机号】不能为空";
            } else {
                if(!isPhoneNumberValid(viteaImport.getUserPhone())){
                    resultMsg = resultMsg + "," + "【*简历手机号】不符合手机号规范"; }
            }

            if(StringUtils.isBlank(viteaImport.getSex())){
                resultMsg = resultMsg + "," + "【*性别】不能为空";
            } else {
                if(!("男".equals(viteaImport.getSex()) || "女".equals(viteaImport.getSex()) || "不限".equals(viteaImport.getSex()))){
                    resultMsg = resultMsg + "," + "【*性别】只能输入男/女/不限三种";
                }
            }

            if(StringUtils.isBlank(viteaImport.getAge())){
                resultMsg = resultMsg + "," + "【*年龄】不能为空";
            } else {
                if(!isNumericRegex(viteaImport.getAge())){
                    resultMsg = resultMsg + "," + "【*年龄】必须是整数";
                } else {
                    int age = Integer.parseInt(viteaImport.getAge());
                    if (age > 100 || age < 0){
                        resultMsg = resultMsg + "," + "【*年龄】必须在合理范围";
                    }
                }
            }

            String cityExpect = viteaImport.getCityExpect();
            if(StringUtils.isBlank(cityExpect)){
                resultMsg = resultMsg + "," + "【*所在地】不能为空";
            } else {
                String replace = cityExpect.replace("，", ",");
                String[] split = replace.split(",");
                if (split.length > 1){
                    resultMsg = resultMsg + "," + "【*所在地】只能填写一个";
                } else {
                    for (String city : split){
                        if (!cityList.contains(city)){
                            resultMsg = resultMsg + "," + "【*所在地】中"+ city +"不合法";
                        }
                    }
                }
            }

            String intendedCity = viteaImport.getIntendedCity();
            if(StringUtils.isBlank(intendedCity)){
                resultMsg = resultMsg + "," + "【*意向城市】不能为空";
            } else {
                String replace = intendedCity.replace("，", ",");
                String[] split = replace.split(",");
                for (String city : split){
                    if (!cityList.contains(city)){
                        resultMsg = resultMsg + "," + "【*意向城市】中"+ city +"不合法";
                    }
                }
            }

            String positionExpect = viteaImport.getPositionExpect();
            if(StringUtils.isBlank(positionExpect)){
                resultMsg = resultMsg + "," + "【*报名职位】不能为空";
            } else {
                String replace = positionExpect.replace("，", ",");
                String[] split = replace.split(",");
                for (String position : split){
                    if (!positionList.contains(position)){
                        resultMsg = resultMsg + "," + "【*报名职位】中"+ position +"不存在";
                    }
                }

            }

            BywEmployee bywEmployee = bywEmployeeMap.get(viteaImport.getEmployeePhone());
            if (bywEmployee == null){
                bywEmployee = employeeService.selectEmployeeByPhone(viteaImport.getEmployeePhone());
                if (bywEmployee == null){
                    resultMsg = resultMsg + "," + "【*手机号】员工不存在";
                } else {
                    bywEmployeeMap.put(viteaImport.getEmployeePhone(), bywEmployee);
                }
            }
            viteaImport.setErrorMsg(resultMsg);
        }
        Map<String, Integer> importNumMap = new HashMap<>();
        int indexData = 0;
        for (ViteaImport viteaImport : viteaImports){
            if (indexData == 0){
                indexData ++;
                continue;
            }
            if (StringUtils.isNotBlank(viteaImport.getErrorMsg())){
                continue;
            }

            BywEmployee bywEmployee = bywEmployeeMap.get(viteaImport.getEmployeePhone());

            BywEmployeeImportVitea employeeImportVitea = employeeImportViteaService.selectBywEmployeeImportViteaByUserPhone(viteaImport.getUserPhone());

            if (employeeImportVitea == null){
                BywEmployeeImportVitea employeeImportViteaAdd = new BywEmployeeImportVitea();
                employeeImportViteaAdd.setUserName(viteaImport.getUserName());
                employeeImportViteaAdd.setUserPhone(viteaImport.getUserPhone());
                if ("男".equals(viteaImport.getSex())){
                    employeeImportViteaAdd.setSex("1");
                } else if ("女".equals(viteaImport.getSex())){
                    employeeImportViteaAdd.setSex("0");
                } else {
                    employeeImportViteaAdd.setSex("2");
                }
                employeeImportViteaAdd.setAge(Integer.parseInt(viteaImport.getAge()));
                employeeImportViteaAdd.setCityExpect(viteaImport.getCityExpect());
                employeeImportViteaAdd.setIntendedCity(viteaImport.getIntendedCity());
                employeeImportViteaAdd.setPositionExpect(viteaImport.getPositionExpect());
                employeeImportViteaAdd.setCreateBy(bywEmployee.getCellphone());
                employeeImportViteaAdd.setCreateTime(DateUtils.getNowDate());
                employeeImportViteaAdd.setUpdateBy(bywEmployee.getCellphone());
                employeeImportViteaAdd.setUpdateTime(employeeImportViteaAdd.getCreateTime());
                employeeImportViteaService.insertBywEmployeeImportVitea(employeeImportViteaAdd);
            } else {
                BywEmployeeImportVitea employeeImportViteaUpdate = new BywEmployeeImportVitea();
                employeeImportViteaUpdate.setUserPhone(employeeImportVitea.getUserPhone());
                employeeImportViteaUpdate.setUserName(viteaImport.getUserName());
                if ("男".equals(viteaImport.getSex())){
                    employeeImportViteaUpdate.setSex("1");
                } else if ("女".equals(viteaImport.getSex())){
                    employeeImportViteaUpdate.setSex("0");
                } else {
                    employeeImportViteaUpdate.setSex("2");
                }
                employeeImportViteaUpdate.setAge(Integer.parseInt(viteaImport.getAge()));
                employeeImportViteaUpdate.setCityExpect(viteaImport.getCityExpect());
                employeeImportViteaUpdate.setIntendedCity(viteaImport.getIntendedCity());
                employeeImportViteaUpdate.setPositionExpect(viteaImport.getPositionExpect());
                employeeImportViteaUpdate.setUpdateBy(bywEmployee.getCellphone());
                employeeImportViteaUpdate.setUpdateTime(DateUtils.getNowDate());
                employeeImportViteaService.updateBywEmployeeImportVitea(employeeImportViteaUpdate);
            }
            BywViteaOwnershipRelation viteaOwnershipRelationQuery = new BywViteaOwnershipRelation();
            viteaOwnershipRelationQuery.setViteaPhone(viteaImport.getUserPhone());
            viteaOwnershipRelationQuery.setUserId(bywEmployee.getId());
            viteaOwnershipRelationQuery.setType(1);
            List<BywViteaOwnershipRelation> bywViteaOwnershipRelations = viteaOwnershipRelationService.selectBywViteaOwnershipRelationList(viteaOwnershipRelationQuery);
            if (CollectionUtils.isEmpty(bywViteaOwnershipRelations)){
                BywViteaOwnershipRelation viteaOwnershipRelationAdd = new BywViteaOwnershipRelation();
                viteaOwnershipRelationAdd.setViteaPhone(viteaImport.getUserPhone());
                viteaOwnershipRelationAdd.setUserId(bywEmployee.getId());
                viteaOwnershipRelationAdd.setType(1);
                viteaOwnershipRelationAdd.setState(0);
                viteaOwnershipRelationAdd.setCreatTime(DateUtils.getNowDate());
                viteaOwnershipRelationService.insertBywViteaOwnershipRelation(viteaOwnershipRelationAdd);
                Integer num = importNumMap.get(viteaImport.getEmployeePhone());
                if (num == null){
                    num = 0;
                }
                importNumMap.put(viteaImport.getEmployeePhone(), num + 1);
            }
            successNum ++;
            viteaImport.setErrorMsg("成功");
        }

        for (Map.Entry<String, Integer> entry : importNumMap.entrySet()) {
            String employeePhone = entry.getKey();
            BywEmployee bywEmployee1 = employeeService.selectEmployeeByPhone(employeePhone);
            Integer num = entry.getValue();
            BywEmployee bywEmployee = new BywEmployee();
            bywEmployee.setCellphone(employeePhone);
            bywEmployee.setVitaeNum(bywEmployee1.getVitaeNum() + num);
            employeeService.updateEmployeeByPhone(bywEmployee);
            BywEmployeeImportInfo employeeImportInfo = new BywEmployeeImportInfo();
            employeeImportInfo.seteId(bywEmployee1.getId());
            employeeImportInfo.setVitaeNum(num);
            employeeImportInfo.setCreateBy(getUsername());
            employeeImportInfo.setCreateTime(DateUtils.getNowDate());
            employeeImportInfo.setUpdateBy(employeeImportInfo.getCreateBy());
            employeeImportInfo.setUpdateTime(employeeImportInfo.getCreateTime());
            employeeImportInfoService.insertBywEmployeeImportInfo(employeeImportInfo);
        }

        ViteaImport viteaImport = viteaImports.get(0);
        if (viteaImport != null){
            viteaImport.setErrorMsg("导入成功，本次导入"+ (viteaImports.size() - 1) +"条，成功"+successNum+"条");
        }

        ExcelUtil<ViteaImport> util2 = new ExcelUtil<ViteaImport>(ViteaImport.class);
        util2.exportExcel(response, viteaImports, "简历导入结果");
    }

    private List<String> positionList(){
        BywPositionType bywPositionTypeQuery = new BywPositionType();
        List<BywPositionType> list = positionTypeService.selectBywPositionList(bywPositionTypeQuery);
        List<String> positionList = new ArrayList<>();

        for (BywPositionType position : list){
            if (position.getParentId() != 0){
                positionList.add(position.getPositionName());
            }
        }
        return positionList;
    }

    public static boolean isPhoneNumberValid(String phoneNumber) {
        // 正则表达式，匹配中国大陆手机号码
        String regex = "^1[3-9]\\d{9}$";
        return phoneNumber.matches(regex);
    }

    public static boolean isNumericRegex(String str) {
        return str.matches("\\d+");
    }

    @ApiOperation("员工导出导入简历模版")
    @PostMapping("/importTemplate")
    public void importTemplate(HttpServletResponse response) throws IOException {
        ClassPathResource classPathResource = new ClassPathResource(File.separator + "importVitaeTemplate.xlsx");
        byte[] data = FileUtil.toByteArray(classPathResource.getInputStream());
        if (data == null) {
            throw new RuntimeException("导入模版不存在");
        }
        String fileName = URLEncoder.encode("员工导入简历模版", "UTF-8").replaceAll("\\+", "%20");
        response.setContentType("application/binary;charset=UTF-8");
        response.setHeader("Content-Disposition", "attachment;fileName=" + fileName);
        response.setHeader("XFileName", fileName + ".xlsx");
        response.setHeader("Response-Type", "Blob");
        response.setContentLength(data.length);
        response.getOutputStream().write(data);
        response.getOutputStream().flush();
        response.getOutputStream().close();
        //ExcelUtil<ViteaImport> util = new ExcelUtil<ViteaImport>(ViteaImport.class);
        //util.importTemplateExcel(response, "简历");
    }

}
